package com.kgcx.common.aspect.utils;

import com.kgcx.common.bean.RequestData;
import org.apache.commons.lang3.ArrayUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.web.bind.annotation.RequestBody;

import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class AspectUtils {
    public static RequestData getRequestData(ProceedingJoinPoint call, MethodSignature msig) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {

        Object target = call.getTarget();

        //拿到请求param参数
        Method getRequestDataMethod = target.getClass().getMethod("getRequestData");
        RequestData rd = null;
        if (null != getRequestDataMethod) {
            rd = (RequestData) getRequestDataMethod.invoke(target);

            //如果表单为ENCTYPE="MULTIPART/FORM-DATA"格式提交,一般就会在定义请求方法的时候添加MultipartHttpServletRequest入参
            // 则需要通过spring的MultipartHttpServletRequest对象获取参数
            if (ArrayUtils.isNotEmpty(msig.getParameterTypes()) && ArrayUtils.contains(msig.getParameterTypes(), HttpServletRequest.class)) {
                Object[] args = call.getArgs();
                if (ArrayUtils.isNotEmpty(args)) {
                    for (Object arg : args) {
                        if (arg instanceof HttpServletRequest) {
                            getRequestDataMethod = target.getClass().getMethod("getRequestData", HttpServletRequest.class);
                            rd = (RequestData) getRequestDataMethod.invoke(target, arg);
                            break;
                        }
                    }
                }
            }
        }
        return rd;
    }

    /**
     * 获取方法入参，一般都为RequestBody，不能在RequestData中读取到
     *
     * @param rd
     */
    public static void findRequestBody(ProceedingJoinPoint call, Method method, RequestData rd) {
        if (null != rd) {
            Object[] args = call.getArgs();
            Annotation[][] parameterAnnotations = method.getParameterAnnotations();
            if (ArrayUtils.isNotEmpty(args)) {
                for (int i = 0; i < args.length; i++) {
                    if (ArrayUtils.isNotEmpty(parameterAnnotations)) {
                        Annotation[] parameterAnnotation = parameterAnnotations[i];
                        if (ArrayUtils.isNotEmpty(parameterAnnotation)) {
                            for (Annotation annotation : parameterAnnotation) {
                                if (annotation instanceof RequestBody) {
                                    rd.put(RequestBody.class.getSimpleName(), args[i]);
                                    return;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
